home *** CD-ROM | disk | FTP | other *** search
/ Pascal Super Library / Pascal Super Library (CW International)(1997).bin / TURB_VIS / TVDMX / DMXGIZMA.PAS < prev    next >
Pascal/Delphi Source File  |  1994-06-20  |  22KB  |  867 lines

  1.  
  2. {■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■}
  3. {                            }
  4. {    DMXGIZMA  --constants, variables and functions    }
  5. {    tvDMX      --data editing project (ver 2.x)    }
  6. {                            }
  7. {    Copyright (c) 1992,94    Randolph Beck        }
  8. {                P.O. Box  56-0487    }
  9. {                Orlando, FL 32856    }
  10. {                CIS:  72361,753        }
  11. {                            }
  12. {■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■}
  13.  
  14. Unit DMXGIZMA;
  15.  
  16. {$V-,X+,O+,D+,B-,R- }
  17.  
  18. interface
  19.  
  20. uses  Objects, Drivers, Views, Dialogs, App, RSet;
  21.  
  22. {$DEFINE tvDMX2A }
  23.  
  24. const
  25.     { tvDMX commands }
  26.     cmDMX        = FirstCmdNum;    { defined in RSET.PAS }
  27.  
  28.     cmDMX_RollCall    = cmDMX +  1;
  29.     cmDMX_Ack        = cmDMX +  2;
  30.     cmDMX_FieldAltered    = cmDMX +  3;
  31.     cmDMX_Draw        = cmDMX +  4;
  32.     cmDMX_DrawData    = cmDMX +  5;
  33.     cmDMX_Lock        = cmDMX +  6;
  34.     cmDMX_LockData    = cmDMX +  7;
  35.     cmDMX_Unlock    = cmDMX +  8;
  36.     cmDMX_UnlockData    = cmDMX +  9;
  37.     cmDMX_FixSize    = cmDMX + 10;
  38.     cmDMX_SetupRecord    = cmDMX + 11;
  39.     cmDMX_WrongKey    = cmDMX + 12;
  40.  
  41.     cmDMX_ZeroizeField    = cmDMX + 13;
  42.     cmDMX_ZeroizeRecord    = cmDMX + 14;
  43.  
  44.     cmDMX_Enter        = cmDMX + 15;
  45.     cmDMX_Left        = cmDMX + 16;
  46.     cmDMX_Right        = cmDMX + 17;
  47.     cmDMX_Home        = cmDMX + 18;
  48.     cmDMX_End        = cmDMX + 19;
  49.  
  50.     cmDMX_goto        = cmDMX + 20;
  51.  
  52.     cmDMX_NextRow    = cmDMX + 21;
  53.     cmDMX_Up        = cmDMX + 22;
  54.     cmDMX_Down        = cmDMX + 23;
  55.     cmDMX_PgUp        = cmDMX + 24;
  56.     cmDMX_PgDn        = cmDMX + 25;
  57.     cmDMX_ScreenTop    = cmDMX + 26;
  58.     cmDMX_ScreenBottom    = cmDMX + 27;
  59.     cmDMX_Top        = cmDMX + 28;
  60.     cmDMX_Bottom    = cmDMX + 29;
  61.  
  62.     cmDMX_DoubleClick    = cmDMX + 30;  { mouse was double-clicked }
  63.     cmDMX_RecIndClicked    = cmDMX + 31;  { record indicator was clicked }
  64.     cmDMX_Reset        = cmDMX + 32;  { tvDMXCOL: reset size of collection }
  65.     cmDMX_ScrollBarChanged =cmDMX+33;  { updates the TDmxLabels views }
  66.     cmDMX_InsertRec    = cmDMX + 34;  { inserts a new record }
  67.  
  68.     cmPRN_NewPage    = cmDMX + 40;  { tvDMXREP: broadcast before new page }
  69.     cmPRN_EndPage    = cmDMX + 41;  { tvDMXREP: broadcast before page end }
  70.     cmPRN_SetOptions    = cmDMX + 42;  { tvDMXREP: open options window }
  71.     cmPRN_LineFeed    = cmDMX + 43;  { tvDMXREP: line feed to printer }
  72.     cmPRN_FormFeed    = cmDMX + 44;  { tvDMXREP: form feed to printer }
  73.     cmPRN_Reset        = cmDMX + 45;  { tvDMXREP: reset printer }
  74.  
  75.     cmUserScreen    = cmDMX + 51;  { tvGizma: invokes User Screen }
  76.     cmToggleSound    = cmDMX + 52;  { tvGizma: toggles BeepOn }
  77.     cmToggleVideo    = cmDMX + 53;  { tvGizma: toggles video mode }
  78.     cmBeep        = cmDMX + 54;  { tvGizma: beeps if BeepOn is TRUE }
  79.     cmChime        = cmDMX + 55;  { tvGizma: broadcast every 30 minutes }
  80.  
  81.  
  82.     { tvDMX view registration numbers }
  83.     rnDMX        = FirstRegNum;    { defined in RSET.PAS }
  84.  
  85.     rnLtdFrame        = rnDMX +  1;    { RegisterTVGIZMA }
  86.     rnLtdWindow        = rnDMX +  2;
  87.  
  88.     rnDmxExtLabels    = rnDMX +  3;    { RegisterTVDMX }
  89.     rnDmxLabels        = rnDMX +  4;
  90.     rnDmxFLabels    = rnDMX +  5;
  91.     rnDmxMLabels    = rnDMX +  6;
  92.     rnDmxRecInd        = rnDMX +  7;
  93.     rnDmxScroller    = rnDMX +  8;
  94.     rnDmxEditor        = rnDMX +  9;
  95.  
  96.     rnDmxHexInd        = rnDMX + 10;    { RegisterTVDMXHEX }
  97.  
  98.     rnDmxEditDlg    = rnDMX + 11;    { RegisterSTDDMX }
  99.     rnInputFields    = rnDMX + 12;
  100.     rnValidFields    = rnDMX + 13;
  101.     rnDmxViewer        = rnDMX + 14;
  102.     rnDmxWindow        = rnDMX + 15;
  103.  
  104.     rnDmxCollectView    = rnDMX + 16;    { RegisterTVDMXCOL }
  105.     rnDmxCollector    = rnDMX + 17;
  106.     rnDmxCollectViewWin    = rnDMX + 18;
  107.     rnDmxCollectorWin    = rnDMX + 19;
  108.  
  109.     rnDmxStreamBuf    = rnDMX + 20;    { RegisterTVDMXBUF }
  110.     rnDmxExpBuf        = rnDMX + 21;
  111.     rnDmxExpRecInd    = rnDMX + 22;
  112.     rnDmxBufWin        = rnDMX + 23;
  113.     rnDmxExpBufWin    = rnDMX + 24;
  114.  
  115.     rnDmxForm        = rnDMX + 25;    { RegisterDMXFORMS }
  116.     rnDmxDlgForm    = rnDMX + 26;
  117.  
  118.  
  119.     cDMX        = #06#07#05#05#01#02;
  120.              {  |  |  |  |    |  | }
  121.   {  1 normal fields -------+  |  |  |    |  | }
  122.   {  2 normal selected field --+  |  |    |  | }
  123.   {  3 read-only selected field --+  |    |  | }
  124.   {  4 locked field -----------------+    |  | }
  125.   {  5 delimiter -----------------------+  | }
  126.   {  6 border -----------------------------+ }
  127.  
  128.  
  129.     { tvDMX field access attributes }
  130.     accNormal     =    0;
  131.     accReadOnly     =    1;
  132.     accHidden     =    2;
  133.     accSkip     =    4;
  134.     accDelimiter =    8;
  135.     accExternal     =  $10;    { for future use }
  136.     accSpecA     =  $20;
  137.     accSpecB     =  $40;
  138.     accSpecC     =  $80;
  139.  
  140.     showTRUE     :  char  =   '■';  { TRUE indicator  }
  141.     showFALSE     :  char  =   ' ';  { FALSE indicator }
  142.     showOVERFLOW :  char  =   '*';  { overflow indicator for numbers }
  143.     showDecPt     :  char  =   '.';  { decimal point display }
  144.     showRadioBtn :  char  =   #7;   { DMX RadioBtn indicator (#4 looks better) }
  145.     showCheckBox :  char  =   'X';  { DMX CheckBox ON indicator }
  146.  
  147.     SizeOfFldCluster    :  integer = sizeof(WORD);
  148.  
  149.     fldSTR        =   'S';  { string field }
  150.     fldSTRNUM        =   '#';  { numeric string field }
  151.     fldCHAR        =   'C';  { character field }
  152.     fldCHARNUM        =   '0';  { numeric character field }
  153.     fldCHARVAL        =   'N';  { dbase formatted numeric field }
  154.     fldBYTE        =   'B';  { byte field }
  155.     fldSHORTINT        =   'J';  { shortint field }
  156.     fldWORD        =   'W';  { word field }
  157.     fldINTEGER        =   'I';  { integer field }
  158.     fldLONGINT        =   'L';  { longint field }
  159.     fldREALNUM        =   'R';  { real number field  (uses TREALNUM) }
  160.     fldBOOLEAN        =   'X';  { boolean value field }
  161.     fldHEXVALUE        =   'H';  { hexadecimal numeric entry }
  162.     fldENUM        =   ^E;   { enumerated field }
  163.     fldBLOb        =   ^M;   { unformatted data field }
  164.     fldCLUSTER        =   'K';  { 'K'=CheckBox; 'k'=RadioButton }
  165.  
  166.     fldZEROMOD        =   'Z';  { zero modifier }
  167.     fldCONTRACTION    =   '`';  { limit of visible text }
  168.  
  169.     fldAPPEND        =   ^G;   { append from pointer }
  170.     fldSITEMS        =   ^I;   { link to chain of TSItem templates }
  171.  
  172.     fldXSPACES        =   ' ';  { spaces --extended code follows <Esc> }
  173.     fldXTABTO        =   ^I;   { tab    --extended code follows <Esc> }
  174.     fldXFIELDNUM    =   ^F;   { fnum   --extended code follows <Esc> }
  175.  
  176.  
  177.   { Complex fields: }
  178.  
  179.     fldDATE     =  ' WW-'^F^Z + ^U+char(12) + ^P+char(2) +
  180.              #0'ZW-'^Z + ^U+char(31) +
  181.              #0'ZZZW '^Z^F + ^P+char(-6) +
  182.              #0 + ^P+char(4);
  183.  
  184.     fldTIME     =  ' WW:'^F^Z + ^U+char(23) +
  185.              #0'ZW '^Z + ^U+char(59) +
  186.              #0'W'^F^H#0;  { seconds are hidden }
  187.  
  188.     fldDATETIME  =  ' WW-'^F^Z + ^U+char(12) + ^P+char(2) +
  189.              #0'ZW-'^Z + ^U+char(31) +
  190.              #0'ZZZW '^Z^F + ^P+char(-6) +
  191.               '\' + ^P+char(4) +
  192.               ' WW:'^F^Z + ^U+char(23) +
  193.              #0'ZW:'^Z     + ^U+char(59) +
  194.              #0'ZW '^Z^F + ^U+char(59);  { seconds are not hidden }
  195.  
  196.     fldNDATE     =  { dBASE-formatted date field }
  197.             ' NN-'^Z^F^V'0' + ^P+char(4) +
  198.              #0'ZN-'^Z^V'0' +
  199.              #0'ZZZN '^Z^F^V'0' + ^P+char(-8) +
  200.              #0^P + char(4);
  201.  
  202.     CurrentCurPos : integer = 0;
  203.  
  204.  
  205. type
  206.     pDMXfieldrec = ^tDMXfieldrec;
  207.     tDMXfieldrec =  RECORD    { these records describe each field for tvDMX }
  208.     Next,Prev    :  pDMXfieldrec;
  209.     access        :  byte;    { read-only, hidden, skip, accSpecX }
  210.     fieldnum    :  byte;    { 1..totalfields (0=none) }
  211.     screentab    :  integer;    { virtual column num. }
  212.     columnwid    :  byte;    { width of field column }
  213.     shownwid    :  byte;    { visible width of column }
  214.     typecode    :  char;    { 's', 'r', etc. }
  215.     fillvalue    :  char;    { #0 or ' ' }
  216.     upperlimit    :  byte;    { maximum value limit }
  217.     showzeroes    :  boolean;    { display zero values }
  218.     truelen        :  byte;    { unformatted text length }
  219.     parenthesis    :  boolean;    { '('/')' characters }
  220.     decimals    :  byte;    { decimal point or cluster value }
  221.     fieldsize    :  integer;    { sizeof (datatype) }
  222.     datatab        :  integer;    { position in record }
  223.     template    :  pstring;    { field template }
  224.     end;
  225.  
  226.  
  227.     showcodes    = (showanyway, shownegative, showregular, showCurrentField);
  228.     showset    =  set of showcodes;    { used when displaying fields }
  229.  
  230.     DmxIDstr    =  string[8];        { contracted template string }
  231.  
  232.  
  233.  
  234.   function  InitAppendFields(ATemplate: pstring) : DmxIDstr;
  235.     { initialize a pointer to more field templates }
  236.  
  237.   function  InitBlobField(Len: integer; AccMode,Default: byte) : DmxIDstr;
  238.     { initialize an unformatted data field }
  239.  
  240.   function  InitEnumField(ShowZ: boolean;  AccMode,Default: byte;
  241.               AItems: PSItem) : DmxIDstr;
  242.     { initialize a tvDMX enum field list }
  243.  
  244.   function  InitTSItemFields(ATemplates: PSItem) : DmxIDstr;
  245.     { initialize a chain of TSItem templates }
  246.  
  247.   procedure DisposeSItems(AItems: PSItem);
  248.     { dispose a chain of TSItems }
  249.  
  250.   function  ReadSItems(var S: TStream) : PSItem;
  251.     { reads strings from a pick list }
  252.  
  253.   procedure WriteSItems(var S: TStream; Items: PSItem);
  254.     { writes strings to a pick list }
  255.  
  256.   function  MaxItemStrLen(AItems: PSItem) : integer;
  257.     { returns the maximum length of the strings in a pick list }
  258.  
  259.   function  SItemsLen(S: PSItem) : integer;
  260.     { returns the cumulative length of the strings in a pick list }
  261.  
  262.   function  DmxStrLen(S: string)  : integer;
  263.     { returns the length of the visible portions of a tvDMX template string }
  264.  
  265.   function  FieldString(fieldrec: pDMXfieldrec;
  266.             Show: showset;  var DataRec )  : string;
  267.     { returns a display string from a tvDMX field record }
  268.  
  269.  
  270. implementation
  271.  
  272.  
  273.   { ══════════════════════════════════════════════════════════════════════ }
  274.  
  275.  
  276. function  InitAppendFields(ATemplate: pstring) : DmxIDstr;
  277. var  S : DmxIDstr;
  278. begin
  279.   S := fldAPPEND + #0#0#0#0#0#0#0;
  280.   Move(ATemplate, S[2], 4);
  281.   InitAppendFields := S;
  282. end;
  283.  
  284.  
  285. function  InitBlobField(Len: integer; AccMode,Default: byte) : DmxIDstr;
  286. var  S : DmxIDstr;
  287. begin
  288.   S := fldBLOb + #0#0#0#0#0 + chr(AccMode) + chr(Default);
  289.   Move(Len, S[2], sizeof(Len));
  290.   InitBlobField := S;
  291. end;
  292.  
  293.  
  294. function  InitEnumField(ShowZ: boolean; AccMode,Default: byte;
  295.             AItems: PSItem) : DmxIDstr;
  296. var  S : DmxIDstr;
  297. begin
  298.   S := fldENUM + #0#0#0#0 + char(ShowZ) + chr(AccMode) + chr(Default);
  299.   Move(AItems, S[2], 4);
  300.   InitEnumField := S;
  301. end;
  302.  
  303.  
  304. function  InitTSItemFields(ATemplates: PSItem) : DmxIDstr;
  305. var  S : DmxIDstr;
  306. begin
  307.   S := fldSITEMS + #0#0#0#0#0#0#0;
  308.   Move(ATemplates, S[2], 4);
  309.   InitTSItemFields := S;
  310. end;
  311.  
  312.  
  313. procedure DisposeSItems(AItems: PSItem);
  314. var  P : PSItem;
  315. begin
  316.   While (AItems <> nil) do
  317.     begin
  318.     P := AItems^.Next;
  319.     If (AItems^.Value <> nil) then DisposeStr(AItems^.Value);
  320.     Dispose(AItems);
  321.     AItems := P;
  322.     end;
  323. end;
  324.  
  325.  
  326. function  ReadSItems(var S: TStream) : PSItem;
  327. var  P,P1 : PSItem;
  328.      n      : integer;
  329. begin
  330.   P1 := nil;
  331.   S.Read(n, sizeof(n));
  332.   While (S.Status = stOK) and (n > 0) do
  333.     begin
  334.     If (P1 = nil) then
  335.       begin
  336.       New(P1);
  337.       P := P1;
  338.       end
  339.      else
  340.       begin
  341.       New(P^.Next);
  342.       P := P^.Next;
  343.       end;
  344.     P^.Value := S.ReadStr;
  345.     P^.Next  := nil;
  346.     Dec(n);
  347.     end;
  348.   ReadSItems := P1;
  349. end;
  350.  
  351.  
  352. procedure WriteSItems(var S: TStream; Items: PSItem);
  353. var  P : PSItem;
  354.      n : integer;
  355. begin
  356.   P := Items;
  357.   n := 0;
  358.   While (P <> nil) do
  359.     begin
  360.     Inc(n);
  361.     P := P^.Next;
  362.     end;
  363.   S.Write(n, sizeof(n));
  364.   While (Items <> nil) do
  365.     begin
  366.     S.WriteStr(Items^.Value);
  367.     Items := Items^.Next;
  368.     end;
  369. end;
  370.  
  371.  
  372. function  MaxItemStrLen(AItems: PSItem) : integer;
  373. var  len : integer;
  374. begin
  375.   len := 0;
  376.   While (AItems <> nil) do
  377.     begin
  378.     If (AItems^.Value <> nil) and (length(AItems^.Value^) > len) then
  379.       len := length(AItems^.Value^);
  380.     AItems := AItems^.Next;
  381.     end;
  382.   MaxItemStrLen := len;
  383. end;
  384.  
  385.  
  386. function  SItemsLen(S: PSItem) : integer;
  387. var  Len : integer;
  388. begin
  389.   Len := 0;
  390.   While (S <> nil) do
  391.     begin
  392.     If (S^.Value <> nil) then Inc(Len, length(S^.Value^));
  393.     S := S^.Next;
  394.     end;
  395.   SItemsLen := Len;
  396. end;
  397.  
  398.  
  399.   { ══════════════════════════════════════════════════════════════════════ }
  400.  
  401.  
  402. function  DmxStrLen(S: string) : integer;
  403. var  i,Len,Wid,Ttl    : integer;
  404.      h            : boolean;
  405.  
  406.     procedure ResetDelimiter(D: boolean);
  407.     begin
  408.       If not h then
  409.     begin
  410.     If (Wid = 0) then Inc(Ttl, Len) else Inc(Ttl, Wid);
  411.     end;
  412.       If D then Inc(Ttl);
  413.       Len := 0;
  414.       Wid := 0;
  415.       h   := FALSE;
  416.     end;
  417.  
  418. begin
  419.   h   := FALSE;
  420.   Ttl := 0;
  421.   Len := 0;
  422.   Wid := 0;
  423.   i   := 0;
  424.   While (i < length(S)) do
  425.     begin
  426.     Inc(i);
  427.     Case upcase(S[i]) of
  428.       '~':
  429.     begin
  430.     Inc(i);
  431.     While (S[i] <> '~') and (i < length(S)) do
  432.       begin
  433.       Inc(Len);
  434.       Inc(i);
  435.       end;
  436.     end;
  437.       ^C, ^P, ^U, ^V:    Inc(i);
  438.       ^H:        h := TRUE;
  439.       ^D:
  440.     begin
  441.     ResetDelimiter(TRUE);
  442.     Inc(i);
  443.     end;
  444.       fldCONTRACTION:    Wid := Len;
  445.       fldCLUSTER:
  446.     begin
  447.     Inc(Len);
  448.     Inc(i);
  449.     end;
  450.       fldENUM:
  451.     begin
  452.     ResetDelimiter(FALSE);
  453.     Inc(Len, MaxItemStrLen(PSItem(S[i+1])));
  454.     Inc(i, sizeof(DmxIDstr) - 1);
  455.     end;
  456.       fldBLOb:
  457.     begin
  458.     ResetDelimiter(FALSE);
  459.     Inc(i, sizeof(DmxIDstr) - 1);
  460.     end;
  461.       fldAPPEND:
  462.     begin
  463.     ResetDelimiter(FALSE);
  464.     Inc(Len, DmxStrLen(pstring(S[i+1])^));
  465.     Inc(i, sizeof(DmxIDstr) - 1);
  466.     end;
  467.       #0,'\','|','│','║':
  468.     begin
  469.     ResetDelimiter(S[i] <> #0);
  470.     end;
  471.       ^A..^Z:    begin  end;
  472.       #27:
  473.     begin
  474.     Inc(i);
  475.     Case upcase(S[i]) of
  476.       fldXSPACES,fldXTABTO:
  477.         begin
  478.         end;
  479.       fldXFIELDNUM:
  480.         begin
  481.         Inc(i);
  482.         end;
  483.       end;
  484.     end;
  485.      else    Inc(Len);
  486.       end;
  487.     end;
  488.   ResetDelimiter(FALSE);
  489.   DmxStrLen := Ttl;
  490. end;
  491.  
  492.  
  493.   { ══════════════════════════════════════════════════════════════════════ }
  494.  
  495.  
  496. function  FieldString(fieldrec: pDMXfieldrec; Show: showset;  var DataRec ) : string;
  497. var  i,j,Len    :  integer;
  498.      C        :  char;
  499.      Numbers    :  boolean;
  500.      ItsBlank    :  boolean;
  501.      Q        :  boolean;
  502.      L        :  longint;
  503.      A,T    :  string;
  504.      R        :  TREALNUM;
  505.      Items    :  PSItem;
  506.  
  507.      Data    :  pointer;
  508.      DataBool    :  pboolean    absolute Data;
  509.      DataByte    :  pbyte    absolute Data;
  510.      DataShort    :  pshortint    absolute Data;
  511.      DataInt    :  pinteger    absolute Data;
  512.      DataWord    :  pword    absolute Data;
  513.      DataLong    :  plongint    absolute Data;
  514.      DataReal    :  PREALNUM    absolute Data;
  515.      DataStr    :  pstring    absolute Data;
  516.  
  517.     function  HexByte(Number: byte)  : string;
  518.     const bts  : array[0..15] of char = '0123456789ABCDEF';
  519.     begin
  520.       HexByte := bts[(Number shr 4) and $0F] + bts[Number and $0F]
  521.     end;
  522.  
  523.     function  BlankField : boolean;
  524.     var  i : word;
  525.     begin
  526.       BlankField := TRUE;
  527.       If Len > 0 then
  528.     For i := 0 to pred(fieldrec^.fieldsize) do
  529.       If DataStr^[i] <> #0 then BlankField := FALSE;
  530.     end;
  531.  
  532.     function  CheckBlank(Zero: boolean) :  boolean;
  533.     begin
  534.       If (Zero) and not ((fieldrec^.showzeroes) or (showanyway in Show)) then
  535.     begin
  536.     fillchar(A[1], Len, ' ');
  537.     A[0]       := chr(Len);
  538.     ItsBlank   := TRUE;
  539.     CheckBlank := TRUE;
  540.     end
  541.        else
  542.     CheckBlank := FALSE;
  543.     end;
  544.  
  545.     function  CheckInfinity : boolean;
  546.     var  w : word;
  547.     begin
  548.       CheckInfinity := FALSE;
  549.       If (sizeof(TREALNUM) = sizeof(Double)) then
  550.     begin
  551.     Move(pstring(DataStr)^[6], w, sizeof(w));
  552.     If (w and $7FF0 = $7FF0) then
  553.       begin
  554.       fillchar(A[1], Len, ' ');
  555.       A[0]       := chr(Len);
  556.       ItsBlank := TRUE;
  557.       CheckInfinity := TRUE;
  558.       end;
  559.     end;
  560.     end;
  561.  
  562.     procedure FormNum(sign: boolean);
  563.     { length of A[] must equal Len + 1 }
  564.     var  i,j : integer;
  565.      cc  : char;
  566.     begin
  567.       With fieldrec^ do
  568.     begin
  569.     If sign and (shownegative in Show) then
  570.       begin
  571.       i := 1;
  572.       While (A[i] = ' ') do Inc(i);
  573.       If (i > 1) then A[pred(i)] := '-';
  574.       end;
  575.     If (parenthesis) then
  576.       begin
  577.       If sign then
  578.         begin
  579.         T[pos('(', T)] := ' ';
  580.         T[pos(')', T)] := ' ';
  581.         end
  582.        else
  583.         begin
  584.         A[pos('-', A)] := ' ';
  585.         If length(A) > succ(Len) then Delete(A, 1,1);
  586.         end;
  587.       end;
  588.     If (A[1] <> ' ') then
  589.       begin
  590.       fillchar(A[1], Len, showOVERFLOW);
  591.       A[0] := chr(Len);
  592.       end
  593.      else
  594.       begin
  595.       Delete(A, 1,1);
  596.       Numbers := TRUE;
  597.       end;
  598.     end;
  599.     end;
  600.  
  601.  
  602. begin
  603.   With fieldrec^ do
  604.     begin
  605.     If (fieldrec = nil) or (access and accHidden <> 0) then
  606.       begin
  607.       FieldString := '';
  608.       Exit;
  609.       end;
  610.     If (template = nil) or (columnwid = 0) then
  611.       begin
  612.       If typecode <> #0 then FieldString := typecode else FieldString := '';
  613.       Exit;
  614.       end;
  615.     If (upcase(typecode) = fldENUM) then
  616.       begin
  617.       fillchar(T[1], columnwid, ' ');
  618.       T[0] := chr(columnwid);
  619.       end
  620.      else
  621.       T  := template^;
  622.     If (fieldsize = 0) then
  623.       begin
  624.       FieldString := T;
  625.       Exit;
  626.       end;
  627.     Data := ptr(seg(DataRec), ofs(DataRec) + datatab);
  628.     Len  := truelen;
  629.     Numbers  := FALSE;
  630.     ItsBlank := FALSE;
  631.     Q     := FALSE;
  632.     C     := upcase(typecode);
  633.     Case C of
  634.  
  635.       fldSTR, fldSTRNUM:            { 'S'/'#' }
  636.     begin
  637.     If DataStr^ <> '' then
  638.       For i := 1 to length(DataStr^) do
  639.         If ord(DataStr^[i]) and $DF <> 0 then Q := TRUE;
  640.     If not CheckBlank(not Q) then
  641.       begin
  642.       fillchar(A[1], Len, ' ');
  643.       Move(DataStr^[1], A[1], length(DataStr^));
  644.       A[0] := chr(Len);
  645.       end;
  646.     end;
  647.  
  648.       fldCHAR, fldCHARNUM:        { 'C'/'0' }
  649.     begin
  650.     If Len > 0 then
  651.       For i := 0 to pred(Len) do
  652.         If ((ord(DataStr^[i]) and $DF) <> 0) then Q := TRUE;
  653.     If not CheckBlank(not Q) then
  654.       begin
  655.       Move(Data^, A[1], Len);
  656.       A[0] := chr(Len);
  657.       end;
  658.     end;
  659.  
  660.       fldCHARVAL:            { 'N' }
  661.     begin
  662.     A[0] := chr(fieldsize);
  663.     Move(Data^, A[1], fieldsize);
  664.     Val(A, R, i);
  665.     If i <> 0 then R := 0.0;
  666.     If not CheckBlank(R = 0.0) then
  667.       begin
  668.       If decimals > 0 then
  669.         begin
  670.         Str(R:(Len + 2):decimals, A);
  671.         Delete(A,(Len + 2) - decimals, 1);
  672.         end
  673.        else
  674.         Str(R:(Len + 1):0, A);
  675.       FormNum(R >= 0);
  676.       end;
  677.     end;
  678.  
  679.       fldBYTE:                { 'B' }
  680.     If not CheckBlank(DataByte^ = 0) then
  681.       begin
  682.       Str(DataByte^:(Len + 1), A);
  683.       FormNum(TRUE);
  684.       end;
  685.  
  686.       fldSHORTINT:            { 'J' }
  687.     If not CheckBlank(DataShort^ = 0) then
  688.       begin
  689.       Str(DataShort^:(Len + 1), A);
  690.       FormNum(DataShort^ >= 0);
  691.       end;
  692.  
  693.       fldWORD:                { 'W' }
  694.     If not CheckBlank(DataWord^ = 0) then
  695.       begin
  696.       Str(DataWord^:(Len + 1), A);
  697.       FormNum(TRUE);
  698.       end;
  699.  
  700.       fldINTEGER:            { 'I' }
  701.     If not CheckBlank(DataInt^ = 0) then
  702.       begin
  703.       Str(DataInt^:(Len + 1), A);
  704.       FormNum(DataInt^ >= 0);
  705.       end;
  706.  
  707.       fldLONGINT:            { 'L' }
  708.     If not CheckBlank(DataLong^ = 0) then
  709.       begin
  710.       Str(DataLong^:(Len + 1), A);
  711.       FormNum(DataLong^ >= 0);
  712.       end;
  713.  
  714.       fldREALNUM:            { 'R' }
  715.     begin
  716.     If not CheckInfinity and not CheckBlank(DataReal^ = 0.0) then
  717.       begin
  718.       If decimals > 0 then
  719.         begin
  720.         Str(DataReal^:(Len + 2):decimals, A);
  721.         Delete(A,(Len + 2) - decimals, 1);
  722.         end
  723.        else
  724.         Str(DataReal^:(Len + 1):0, A);
  725.       If (abs(DataReal^) > 1e35) then
  726.         begin
  727.         A := '**********************************';
  728.         If (DataReal^ < 0.0) then A[1] := '-';
  729.         end;
  730.       FormNum(DataReal^ >= 0);
  731.       end;
  732.     end;
  733.  
  734.       fldBOOLEAN:            { 'X' }
  735.     begin
  736.     If (Len = 0) then
  737.       begin
  738.       If DataBool^ then A := '' else ItsBlank := TRUE;
  739.       end
  740.      else
  741.       begin
  742.       If not CheckBlank(not DataBool^) then
  743.         begin
  744.         If DataBool^ then
  745.           fillchar(A[1], Len, showTRUE)
  746.          else
  747.           fillchar(A[1], Len, showFALSE);
  748.         A[0] := chr(Len);
  749.         end;
  750.       end;
  751.     end;
  752.  
  753.       fldHEXVALUE:            { 'H' }
  754.     If not CheckBlank(BlankField) then
  755.       begin
  756.       A  := '';
  757.       For i := 0 to pred(fieldsize) do A := hexbyte(ord(DataStr^[i])) + A;
  758.       If (length(A) > Len) then Delete(A, 1,1);
  759.       end;
  760.  
  761.       fldENUM:                { ^P  }
  762.     If not CheckBlank(DataByte^ = 0) then
  763.       begin
  764.       A  := '';
  765.       Items := PSItem(template);
  766.       i    := DataByte^;
  767.       While (i > 0) do
  768.         begin
  769.         Dec(i);
  770.         If (Items <> nil) then Items := Items^.Next else i := 0;
  771.         end;
  772.       If (Items <> nil) and (Items^.Value <> nil) and (Items^.Value^ <> '') then
  773.         begin
  774.         Move(Items^.Value^[1], T[1], length(Items^.Value^));
  775.         end;
  776.       end;
  777.  
  778.       fldCLUSTER:            { 'K' }
  779.     begin
  780.     L := 0;
  781.     If (sizeof(L) > fieldsize) then
  782.       Move(Data^, L, fieldsize)
  783.      else
  784.       Move(Data^, L, sizeof(L));
  785.     If (typecode >= 'a') then  { RadioButton }
  786.       begin
  787.       If (L = decimals) then
  788.         fillchar(A[1], Len, showRadioBtn)
  789.        else
  790.         fillchar(A[1], Len, ' ');
  791.       A[0] := chr(Len);
  792.       end
  793.      else
  794.       begin
  795.       If odd(L shr decimals) then
  796.         fillchar(A[1], Len, showCheckBox)
  797.        else
  798.         fillchar(A[1], Len, ' ');
  799.       A[0] := chr(Len);
  800.       end;
  801.     end;
  802.  
  803.       end;  { case of C }
  804.  
  805.     If ItsBlank then
  806.       begin
  807.       fillchar(T[1], length(T), ' ');
  808.       end
  809.      else
  810.       If A <> '' then
  811.     begin
  812.     j  := length(A);
  813.     Q  := (fieldrec^.decimals > 0);
  814.     For i := length(T) downto 1 do
  815.       begin
  816.       If Q and (showanyway in Show) and (j <= CurrentCurPos) then Q := FALSE;
  817.       If (ord(T[i]) and $FE = 0) then
  818.         begin
  819.         If j > 0 then
  820.           begin
  821.           If Q then If (A[j] = '0') then A[j] := ' ' else Q := FALSE;
  822.           If (T[i] = #0) or (A[j] > ' ') then
  823.         T[i] := A[j]
  824.            else
  825.         begin
  826.         T[i] := '0';
  827.         Q := FALSE;
  828.         end;
  829.           Dec(j);
  830.           end;
  831.         end
  832.        else
  833.         begin
  834.         If Q and (T[i] = showDecPt) then
  835.           begin
  836.           Q := FALSE;
  837.           T[i] := ' ';
  838.           end;
  839.         If Numbers and (T[i] = ',') then
  840.           begin
  841.           If (j <= 0) then T[i] := ' '
  842.            else
  843.         begin
  844.         If (A[j] in [' ','-']) then
  845.           begin
  846.           T[i] := A[j];
  847.           Dec(j);
  848.           end;
  849.         end;
  850.           end;
  851.         end;
  852.       end;
  853.     end;
  854.     end;
  855.  
  856.   CurrentCurPos := 0;
  857.   FieldString := T;
  858.  
  859. end;  { FieldString() }
  860.  
  861.  
  862.   { ══════════════════════════════════════════════════════════════════════ }
  863.  
  864.  
  865.  
  866. End.
  867.